package com.openbravo.data.loader.dialect.MySQL;

import com.openbravo.data.loader.dialect.AbstractDBDialect;
import com.openbravo.data.loader.dialect.AbstractDDLFactory;
import com.openbravo.data.loader.serialize.Datas;
import e.odbo.data.AbstractConfigEntry;
import e.odbo.data.format.Formats;
import e.odbo.data.model.*;
import e.odbo.data.util.StringUtils;

import java.util.Date;
import java.util.List;

public class MySQLDDLFactory extends AbstractDDLFactory {

    public static String TABLE_characterSet="mysql.ddl.characterSet";
    public static String TABLE_collate="mysql.ddl.collate";
    public static String TABLE_engine="mysql.ddl.engine";

    static {
        defaultConfigs.put(TABLE_characterSet, "utf8mb4");
        defaultConfigs.put(TABLE_collate, "utf8mb4_unicode_ci");
    }

    public static ColumnType DATETIME=new ColumnType<Date>("DATETIME", Datas.TIMESTAMP, Formats.TIMESTAMP){};

    public static class Config{
        public static AbstractConfigEntry<String> CharacterSet(String value) {
            return new AbstractConfigEntry(TABLE_characterSet, value) {
            };
        }


        public static AbstractConfigEntry<String> Collate(String value) {
            return new AbstractConfigEntry(TABLE_collate, value) {
            };
        }

        public static AbstractConfigEntry<String> Engine(String value) {
            return new AbstractConfigEntry(TABLE_engine, value) {
            };
        }
    }

    private String buildCharactSet() {
        return "CHARACTER SET " + getConfig(TABLE_characterSet) + " COLLATE " + getConfig(TABLE_collate);
    }


    public MySQLDDLFactory(AbstractDBDialect dbDialect) {
        super(dbDialect);
        //此初可加专用类型映射
        //this.dialectTypeMap.put(ColumnType.BOOLEAN.getType(),"mysql转用映射类")；
        this.dialectTypeMap.put(ColumnType.TIMESTAMP.getType(),DATETIME);
    }


    /*示例：
         CREATE TABLE `organ` (
           `id` int(11) NOT NULL AUTO_INCREMENT,
           `userId` int(11) DEFAULT NULL,
           `type` int(11) DEFAULT NULL,
           `score` int(11) DEFAULT NULL,
           PRIMARY KEY (`id`),
           KEY `uk` (`userId`),
           CONSTRAINT `uk` FOREIGN KEY (`userId`) REFERENCES `user` (`userId`) ON DELETE CASCADE ON UPDATE CASCADE
         ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

         CREATE TABLE IF NOT EXISTS unlock_speed ( 
             id bigint(20) unsigned not null auto_increment,
             device_name varchar(50) not null comment '机型号',
             version varchar(50) not null comment '版本号', 
             release_type varchar(20) not null sample '' comment '版本类型',
             time_all bigint(20) unsigned not null sample 0 comment '解锁总时间',
             date varchar(20) not null comment '日期', 
             primary key(id), 
             key idx_name_type_date (device_name,release_type,date)
           )ENGINE=InnoDB DEFAULT CHARSET=utf8;
    */

    @Override
    public String createDataBase(String dataBaseName) {
        return "CREATE DATABASE " + dataBaseName + " DEFAULT " + buildCharactSet()  +getDialectTailed();
    }


    public String generatePK(List<Column> columns){
        String ret="PRIMARY KEY (";
        for(Column column:columns)
            ret+=column.getName()+",";
         return ret.substring(0,ret.length()-1)+")";
    }

    public  String generateColumn(Column column){
        String ret=column.getName();
        ColumnType columnType=this.transformColumnTypeToDialect(column,MySQL.NAME);
        ret+= " "+columnType.buildTypeString();
        if(ColumnFlag.isNotNull(column.getColumnFlag()))
            ret+=" NOT NULL ";
        if(ColumnFlag.isUnique(column.getColumnFlag()))
            ret+=" UNIQUE ";

        if(columnType.getDefaultValue()!=null)
            ret+=" DEFAULT "+columnType.getDefaultValue();
        if(ColumnFlag.isAutoGreater(column.getColumnFlag()))
            ret+=" AUTO_INCREMENT ";
        if(column.getComment()!=null)
            ret+=" COMMENT '"+column.getComment()+"'";
        return ret;
    }

    public String generateIndex(String name, String[] indexColumn){
        String ret=" KEY '"+name+"'("+ StringUtils.join(indexColumn,',')+")";
        return ret;
    }

    public String generateTableDialect(Table table){
        String ret=getConfig(TABLE_engine)!=null?"ENGINE="+getConfig(TABLE_engine):"";
        ret+=" DEFAULT CHARSET="+getConfig(TABLE_characterSet);
        if(table.getComment()!=null)
            ret+=" COMMENT '"+table.getComment()+"'";
        return ret;
    }



    public String generateForeign(TableForeignKey foreignKey){
        String ret="CONSTRAINT `"+foreignKey.getName()+"` FOREIGN KEY ("+StringUtils.join(foreignKey.getColumns(),',')+")";
        ret+=" REFERENCES "+foreignKey.getRefTable()+"("+StringUtils.join(foreignKey.getRefColumns(),',')+")";
        if(foreignKey.isCascadeFlag_del())
            ret+=" ON DELETE "+foreignKey.getCascadeFlag_del().getName()+" ";
        if(foreignKey.isCascadeFlag_update())
            ret+=" ON UPDATE "+foreignKey.getCascadeFlag_update().getName()+" ";

        return ret;
    }

}
